#include <stdio.h>
#include <sys/stat.h>  // 包含 mkdir() 函数
#include <sys/types.h> // 包含 mode_t 类型
#include <string.h>
#include <libssh/libssh.h>
//#include <stdio.h>
//#include <stdlib.h>
//#include <stdio.h>
//#include <stdlib.h>
#include <sys/stat.h>

struct FilesInfo {
    char *file_name;
    char *remote_path;
    char *node_name;

};

typedef struct {
    char old_ipaddr;
    char new_ipaddr;
    char comms[100][256];
    size_t comms_cnt;
    struct FilesInfo filesInfo[24];
    int files_info_count;
} ReplaceInfo;


int createDir(const char *path) {
    mode_t mode = 0755;                 // 目录权限（rwxr-xr-x）

    // 调用 mkdir 创建目录
    int result = mkdir(path, mode);

    if (result == 0) {
        printf("目录创建成功: %s\n", path);
        return 0;
    } else {
        perror("创建目录失败");
        return 1;
    }
}

//ReplaceInfo replaceStr(const char *old_ipaddr, char *new_ipaddr[], const char *node_name){
//    ReplaceInfo r;
//
//
//    printf("start replaceStr: \n");
//    if (strcmp(node_name, "node1") == 0){
//        sprintf(r.comms[0], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", old_ipaddr, new_ipaddr[1], node_name);
//        sprintf(r.comms[1], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", old_ipaddr, new_ipaddr[1], node_name);
//        sprintf(r.comms[2], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n0.conf", old_ipaddr, new_ipaddr[1], node_name);
//    } else if (strcmp(node_name, "node2") == 0) {
//        sprintf(r.comms[0], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", old_ipaddr, new_ipaddr[2], node_name);
//        sprintf(r.comms[1], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", old_ipaddr, new_ipaddr[2], node_name);
//        sprintf(r.comms[2], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n1.conf", old_ipaddr, new_ipaddr[2], node_name);
//    }else if (strcmp(node_name, "node3") == 0) {
//        sprintf(r.comms[0], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", old_ipaddr, new_ipaddr[3], node_name);
//        sprintf(r.comms[1], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", old_ipaddr, new_ipaddr[3], node_name);
//        sprintf(r.comms[2], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n2.conf", old_ipaddr, new_ipaddr[3], node_name);
//    } else if (strcmp(node_name, "all") == 0) {
//        printf("start replaceStr all: \n");
//        for (int i = 0; i < 200; i++){
//            if (i < 100){
//                sprintf(r.comms[i], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.141", new_ipaddr[1], "node1");
//            }
//            printf("Argument %d: %s\n", i, new_ipaddr[i]);
//
//        }
//        sprintf(r.comms[0], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[1], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[2], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n0.conf", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[3], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[4], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[5], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[6], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[7], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.141", new_ipaddr[1], "node1");
//        sprintf(r.comms[24], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[10], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[11], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n0.conf", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[3], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[4], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[5], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[6], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[7], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.142", new_ipaddr[2], "node1");
//        sprintf(r.comms[18], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.143", new_ipaddr[3], "node1");
//        sprintf(r.comms[19], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.143", new_ipaddr[3], "node1");
//        sprintf(r.comms[20], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n0.conf", "192.168.31.143", new_ipaddr[3], "node1");
//        sprintf(r.comms[3], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.143", new_ipaddr[3], "node1");
//        sprintf(r.comms[4], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.143", new_ipaddr[3], "node1");
//        sprintf(r.comms[5], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.143", new_ipaddr[3], "node1");
//        sprintf(r.comms[6], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.143", new_ipaddr[3], "node1");
//        sprintf(r.comms[7], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.143", new_ipaddr[3], "node1");
//
//        sprintf(r.comms[8], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[9], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[10], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n1.conf", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[11], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[12], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[13], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[14], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[15], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.141", new_ipaddr[1], "node2");
//        sprintf(r.comms[12], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[13], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[14], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n1.conf", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[11], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[12], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[13], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[14], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[15], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.142", new_ipaddr[2], "node2");
//        sprintf(r.comms[21], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.143", new_ipaddr[3], "node2");
//        sprintf(r.comms[22], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.143", new_ipaddr[3], "node2");
//        sprintf(r.comms[23], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n1.conf", "192.168.31.143", new_ipaddr[3], "node2");
//        sprintf(r.comms[11], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.143", new_ipaddr[3], "node2");
//        sprintf(r.comms[12], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.143", new_ipaddr[3], "node2");
//        sprintf(r.comms[13], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.143", new_ipaddr[3], "node2");
//        sprintf(r.comms[14], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.143", new_ipaddr[3], "node2");
//        sprintf(r.comms[15], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.143", new_ipaddr[3], "node2");
//
//        sprintf(r.comms[16], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[17], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[18], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n2.conf", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[19], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[20], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[21], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[22], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[23], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.141", new_ipaddr[1], "node3");
//        sprintf(r.comms[15], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[16], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[17], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n2.conf", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[19], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[20], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[21], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[22], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[23], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.142", new_ipaddr[2], "node3");
//        sprintf(r.comms[24], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/sentinel.conf", "192.168.31.143", new_ipaddr[3], "node3");
//        sprintf(r.comms[25], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/redis.conf", "192.168.31.143", new_ipaddr[3], "node3");
//        sprintf(r.comms[26], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/broker-n2.conf", "192.168.31.143", new_ipaddr[3], "node3");
//        sprintf(r.comms[19], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/cluster.conf", "192.168.31.143", new_ipaddr[3], "node3");
//        sprintf(r.comms[20], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/miniod", "192.168.31.143", new_ipaddr[3], "node3");
//        sprintf(r.comms[21], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-graphd.conf", "192.168.31.143", new_ipaddr[3], "node3");
//        sprintf(r.comms[22], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-metad.conf", "192.168.31.143", new_ipaddr[3], "node3");
//        sprintf(r.comms[23], "sed -i 's/%s/%s/g' /home/aliee/test-files/%s/nebula-storaged.conf", "192.168.31.143", new_ipaddr[3], "node3");
//
//
//    }
//
//    return r;
//}

ReplaceInfo replaceStr(const char *files_path, char new_node_ipaddr[][64],int new_ipaddr_count, const char *node_name) {
    ReplaceInfo r = {0};
    printf("start replaceStr123 \n");

    char *nodes[] = {"node1", "node2", "node3"};
    char *common_files[] = {
            "sentinel.conf", "redis.conf", "cluster.conf", "miniod",
            "nebula-graphd.conf", "nebula-metad.conf", "nebula-storaged.conf"
    };
    char *conf_dir[] = {
            "/opt/nancal/base/redis", "/opt/nancal/base/redis", "/opt/nancal/base/nacos", "/opt/nancal/base/minio",
            "/opt/nancal/base/nebula","/opt/nancal/base/nebula","/opt/nancal/base/nebula"
    };
    char *broker_files[] = {"broker-n0.conf", "broker-n1.conf", "broker-n2.conf"};
    char *old_ips[] = {"192.168.31.141", "192.168.31.142", "192.168.31.143"};

    int comm_index = 0;
    int files_info_index = 0;

    if (strcmp(node_name, "node1") == 0) {
        printf("start replaceStr456 \n");
        // node1 的特定文件
        const char *files[] = {"sentinel.conf", "redis.conf", "broker-n0.conf"};
        for (int i = 0; i < 3; i++) {
            snprintf(r.comms[comm_index++], 256,
                     "sed -i 's/%s/%s/g' %s/%s/%s",
                     old_ips[i], new_node_ipaddr[1], files_path, "node1", files[i]
            );
        }
    } else if (strcmp(node_name, "all") == 0) {
        printf("start replaceStr456 \n");
        // 遍历所有节点和IP
        for (int node_idx = 0; node_idx < new_ipaddr_count; node_idx++) {
            printf("start replaceStr789 \n");
            const char *current_node = nodes[node_idx];
            const char *broker_file = broker_files[node_idx];

            // 通用文件处理
            for (int file_idx = 0; file_idx < 7; file_idx++) {
                printf("start replaceStr10 11 12 \n");
                for (int ip_idx = 0; ip_idx < new_ipaddr_count; ip_idx++) {
                    printf("start replaceStr13 14 15 \n");
                    snprintf(r.comms[comm_index++], 256,
                             "sed -i 's/%s/%s/g' %s/%s/%s",
                             old_ips[ip_idx], new_node_ipaddr[ip_idx], files_path, current_node, common_files[file_idx]
                    );
                    r.comms_cnt++;
                }
            }

            // Broker文件特殊处理
            for (int ip_idx = 0; ip_idx < new_ipaddr_count; ip_idx++) {
                snprintf(r.comms[comm_index++], 256,
                         "sed -i 's/%s/%s/g' %s/%s/%s",
                         old_ips[ip_idx], new_node_ipaddr[ip_idx], files_path, current_node, broker_file
                );
                r.comms_cnt++;
            }
        }
    }
    printf("start replaceStr aaa \n");

    for (int node_idx = 0; node_idx < new_ipaddr_count; node_idx++) {
        int files_name_index = 0;
        for (int i = 0; i < 7; i++) {
            r.filesInfo[files_info_index].remote_path = conf_dir[files_name_index];
            r.filesInfo[files_info_index].node_name = nodes[node_idx];
            r.filesInfo[files_info_index].file_name = common_files[files_name_index];
            files_info_index++;
            files_name_index++;
            printf("files_info_index: %d", files_info_index);
        }
        r.filesInfo[files_info_index].remote_path = "/opt/nancal/base/rocketmq";
        r.filesInfo[files_info_index].node_name = nodes[node_idx];
        r.filesInfo[files_info_index].file_name = broker_files[node_idx];
        files_info_index++;
        printf("files_info_index===========================: %d \n", files_info_index);
        r.files_info_count = files_info_index;
    }

    return r;
}


int execute_remote_command(ssh_session session, const char *command) {
    ssh_channel channel = ssh_channel_new(session);
    if (channel == NULL) return SSH_ERROR;

    int rc = ssh_channel_open_session(channel);
    if (rc != SSH_OK) {
        ssh_channel_free(channel);
        return rc;
    }

    rc = ssh_channel_request_exec(channel, command);
    if (rc != SSH_OK) {
        ssh_channel_close(channel);
        ssh_channel_free(channel);
        return rc;
    }

    char buffer[1024];
    int nbytes;
    while ((nbytes = ssh_channel_read(channel, buffer, sizeof(buffer), 0)) > 0) {
        fwrite(buffer, 1, nbytes, stdout);
    }

    ssh_channel_send_eof(channel);
    ssh_channel_close(channel);
    ssh_channel_free(channel);
    return SSH_OK;
}

int upload_file(ssh_session session, const char *local_path, const char *remote_path) {
    // 打开本地文件
    FILE *local_file = fopen(local_path, "rb");
    if (!local_file) {
        perror("无法打开本地文件");
        return SSH_ERROR;
    }

    // 获取文件大小
    struct stat file_stat;
    if (stat(local_path, &file_stat) != 0) {
        perror("获取文件大小失败");
        fclose(local_file);
        return SSH_ERROR;
    }
    size_t file_size = file_stat.st_size;

    // 创建SCP会话
    ssh_scp scp = ssh_scp_new(session, SSH_SCP_WRITE, remote_path);
    if (!scp) {
        fprintf(stderr, "SCP会话创建失败: %s\n", ssh_get_error(session));
        fclose(local_file);
        return SSH_ERROR;
    }

    // 初始化SCP
    int rc = ssh_scp_init(scp);
    if (rc != SSH_OK) {
        fprintf(stderr, "SCP初始化失败: %s\n", ssh_get_error(session));
        ssh_scp_free(scp);
        fclose(local_file);
        return rc;
    }

    // 设置文件权限（0644）
    rc = ssh_scp_push_file(scp, remote_path, file_size, 0644);
    if (rc != SSH_OK) {
        fprintf(stderr, "SCP文件推送失败: %s\n", ssh_get_error(session));
        ssh_scp_free(scp);
        fclose(local_file);
        return rc;
    }

    // 读取并发送文件内容
    char buffer[4096];
    size_t total_sent = 0;
    while (total_sent < file_size) {
        size_t read_size = fread(buffer, 1, sizeof(buffer), local_file);
        if (read_size <= 0) break;

        rc = ssh_scp_write(scp, buffer, read_size);
        if (rc != SSH_OK) {
            fprintf(stderr, "文件传输中断: %s\n", ssh_get_error(session));
            break;
        }
        total_sent += read_size;
    }

    // 清理资源
    fclose(local_file);
    ssh_scp_close(scp);
    ssh_scp_free(scp);

    return (total_sent == file_size) ? SSH_OK : SSH_ERROR;
}